package test;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class 多线程并发执行循环 {

    public volatile static int flag = 1;

    private static ReentrantLock lock = new ReentrantLock();
    private static Condition conditionA = lock.newCondition();
    private static Condition conditionB = lock.newCondition();
    private static Condition conditionC = lock.newCondition();

    public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printA();
            }
        },"A");
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printB();
            }
        },"B");
        Thread t3 = new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                printC();
            }
        },"C");
        t1.start();
        t2.start();
        t3.start();
    }

    private static void printA() {
        lock.lock();
        if (flag != 1) {
            try {
                conditionA.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName());
        flag = 2;
        conditionB.signal();

        lock.unlock();
    }

    private static void printB() {
        lock.lock();
        if (flag != 2) {
            try {
                conditionB.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName());
        flag = 3;
        conditionC.signal();

        lock.unlock();
    }

    private static void printC() {
        lock.lock();
        if (flag != 3) {
            try {
                conditionC.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName());
        flag = 1;
        conditionA.signal();

        lock.unlock();
    }

}
